/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/5/29 19:09
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.aurora.core.container.bootstrap;

import com.hyacinth.aurora.core.context.AppConfig;
import com.hyacinth.aurora.mvc.AuroraContext;
import com.hyacinth.aurora.core.context.ThreadLocalHolder;
import com.hyacinth.aurora.core.bean.BeanManager;
import com.hyacinth.aurora.core.exception.AuroraException;
import com.hyacinth.aurora.core.plugin.PluginHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.hyacinth.aurora.constant.Constant.SystemProperties.APPLICATION_THREAD_SHUTDOWN_NAME;

/**
 * 启动引导类
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
public abstract class AuroraBootstrap implements BootStrap {

    final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    static final AppConfig appConfig = AppConfig.INSTANCE;

    @Override
    public void start() {
        try {
            // 服务启动
            doStart();
            // 打印启动日志
            printStartLog();
            // 注册关闭服务钩子
            registShutdownHook();
            // 注册服务
            joinServer();
        } catch (Throwable ex) {
            LOGGER.error("start up aurora server error!!!");
            throw new AuroraException(ex);
        }
    }

    /**
     * 打印启动日志
     */
    private void printStartLog() {
        Long start = ThreadLocalHolder.getLocalTime();
        long end = System.currentTimeMillis();
        LOGGER.info("Aurora started on port: {}.cost {}ms", appConfig.getPort(), end - start);
        LOGGER.info(">>>>> access http://{}:{}{} <<<<<","127.0.0.1",appConfig.getPort(),appConfig.getServerContextPath());
    }

    /**
     * 注册关闭钩子
     */
    private void registShutdownHook() {
        ShutDownThread shutDownThread = new ShutDownThread();
        shutDownThread.setName(APPLICATION_THREAD_SHUTDOWN_NAME);
        Runtime.getRuntime().addShutdownHook(shutDownThread);
    }

    /**
     * 关闭线程
     */
    private class ShutDownThread extends Thread {
        @Override
        public void run() {
            // 系统注销
            shutdown();
        }

    }

    /**
     * 关闭服务
     */
    @Override
    public void shutdown() {
        try {
            LOGGER.info("Aurora server stop...");
            // 删除上下文
            AuroraContext.removeContext();
            // 释放bean
            BeanManager.getInstance(BeanManager.class).destroy();
            // 销毁插件
            PluginHelper.getInstance(PluginHelper.class).destroy();
            // 关闭资源
            release();
            LOGGER.info("Aurora server has been successfully stopped.");
        } catch (Throwable e) {
            throw new AuroraException("注销服务出错", e);
        }
    }

    protected abstract void doStart() throws Exception;

    protected abstract void joinServer();

    protected abstract void release();
}
